package net.adetech.utils;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by sunfeihu on 2016/10/14.
 */
public class UtilsEncryption {

    private static String encryptMode(byte[] keybyte, String src, String Algorithm, String coding) {
        try {
            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
            Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.ENCRYPT_MODE, deskey);
            return byte2Hex(c1.doFinal(src.getBytes(coding)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String decryptMode(byte[] keybyte, String src, String Algorithm, String coding) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
            UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
        SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
        Cipher c1 = Cipher.getInstance(Algorithm);
        c1.init(Cipher.DECRYPT_MODE, deskey);
        return new String(c1.doFinal(hex2Byte(src)), coding);
    }

    private static String byte2Hex(byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs.toUpperCase();
    }

    private static byte[] hex2Byte(String str) {
        if (str == null)
            return null;
        str = str.trim();
        int len = str.length();
        if (len == 0 || len % 2 == 1)
            return null;
        byte[] b = new byte[len / 2];
        try {
            for (int i = 0; i < str.length(); i += 2) {
                b[i / 2] = (byte) Integer.decode("0x" + str.substring(i, i + 2)).intValue();
            }
            return b;
        } catch (Exception e) {
            return null;
        }
    }

    public static String dataEncryption3DES(String secretKey, String str) throws UnsupportedEncodingException {
        return dataEncryption3DES(secretKey, str, "utf-8");
    }


    public static String md5(String str) {
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算md5函数
            md.update(str.getBytes());
            // digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
            // BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
            return new BigInteger(1, md.digest()).toString(16);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String dataEncryption3DES(String secretKey, String str, String coding) throws UnsupportedEncodingException {
        final byte[] keyBytes = secretKey.getBytes();
        return encryptMode(keyBytes, str, "DESede", coding);
    }

    public static String dataEncryption3DES(String str) throws UnsupportedEncodingException {
        final byte[] keyBytes = "jerehjereijerehjerei1234".getBytes();
        return encryptMode(keyBytes, str, "DESede", "utf-8");
    }

    public static String dataDecryption3DES(String str) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException,
            IllegalBlockSizeException, BadPaddingException {
        final byte[] keyBytes = "jerehjereijerehjerei1234".getBytes();
        return decryptMode(keyBytes, str, "DESede", "utf-8");
    }

    public static String dataDecryption3DES(String secretKey, String str) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
            UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
        return dataDecryption3DES(secretKey, str, "utf-8");
    }

    public static String dataDecryption3DES(String secretKey, String str, String coding) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
            UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
        final byte[] keyBytes = secretKey.getBytes();
        return decryptMode(keyBytes, str, "DESede", coding);
    }

}
